package model

import (
	"database/sql"
	"encoding/json"
	"time"
	"errors"
)

type SecuritiesCompany struct {
	Id                    int    `json:"id"`
	Name                  string `json:"name"`
	Img                   string `json:"img"`
	OfficialAdvantage     string `json:"official_advantage"`
	ThickSnowAdvantage    string `json:"thick_snow_advantage"`
	Addr                  string `json:"addr"`
	TotalPromotionFee     int    `json:"total_promotion_fee"`
	PromotionOfficerAward int    `json:"promotion_officer_award"`
	ApprenticeAward       int    `json:"apprentice_award"`
	CreatedDate           int    `json:"created_date"`
	UpdatedDate           int    `json:"updated_date"`
	Rules                 string `json:"rules"`
	Status                int    `json:"status"`
}

func redisSecuritiesCompany() (ret []*SecuritiesCompany, err error) {
	err = rdb.Del(ctx, "securities_company").Err()
	if err != nil {
		return ret, err
	}

	rows, err := db.Query("SELECT * FROM securities_company ORDER BY updated_date DESC")
	if err != nil {
		return ret, err
	}

	defer rows.Close()

	for rows.Next() {
		s := SecuritiesCompany{}
		if err := rows.Scan(&s.Id, &s.Name, &s.Img, &s.OfficialAdvantage, &s.ThickSnowAdvantage, &s.Addr, &s.TotalPromotionFee, &s.PromotionOfficerAward, &s.ApprenticeAward, &s.CreatedDate, &s.UpdatedDate, &s.Rules, &s.Status); err != nil {
			return ret, err
		}

		ret = append(ret, &s)

		jsonStu, err := json.Marshal(s)
		if err != nil {
			return ret, err
		}

		err = rdb.RPush(ctx, "securities_company", jsonStu).Err()
		if err != nil {
			return ret, err
		}
	}

	return ret, nil
}

func (s *SecuritiesCompany) GetSecuritiesCompany() (ret []*SecuritiesCompany, err error) {
	vals, err := rdb.LRange(ctx, "securities_company", 0, -1).Result()
	if err != nil {
		return nil, err
	}

	if len(vals) > 0 {
		for _, v := range vals {
			s := SecuritiesCompany{}
			err := json.Unmarshal([]byte(v), &s)
			if err != nil {
				return ret, err
			}

			ret = append(ret, &s)
		}

		return ret, nil
	}

	ret, err = redisSecuritiesCompany()
	if err != nil {
		return ret, err
	}

	return ret, nil
}

func (s *SecuritiesCompany) GetSecuritiesCompanyDetails(id int) (ret SecuritiesCompany, err error) {
	stmt, err := db.Prepare("SELECT name, img, official_advantage, addr, rules FROM securities_company WHERE id=?")
	if err != nil {
		return ret, err
	}

	err = stmt.QueryRow(id).Scan(&ret.Name, &ret.Img, &ret.OfficialAdvantage, &ret.Addr, &ret.Rules)
	if err != nil && err != sql.ErrNoRows {
		return ret, err
	}

	if err == sql.ErrNoRows {
		return ret, errors.New("无效id")
	}

	return ret, nil
}

func (s *SecuritiesCompany) CreateSecuritiesCompany(se *SecuritiesCompany) error {
	stmt, err := db.Prepare("SELECT id FROM securities_company WHERE name=?")
	if err != nil {
		return err
	}

	err = stmt.QueryRow(se.Name).Scan(&s.Id)
	if err != nil && err != sql.ErrNoRows {
		return err
	}

	if err == sql.ErrNoRows {
		stmt, err := db.Prepare("INSERT securities_company SET name=?, img=?, official_advantage=?, thick_snow_advantage=?, addr=?, total_promotion_fee=?, promotion_officer_award=?, apprentice_award=?, created_date=?, updated_date=?, rules=?, status=?")
		if err != nil {
			return err
		}

		_, err = stmt.Exec(se.Name, se.Img, se.OfficialAdvantage, se.ThickSnowAdvantage, se.Addr, se.TotalPromotionFee, se.PromotionOfficerAward, se.ApprenticeAward, time.Now().Unix(), time.Now().Unix(), se.Rules, 1)
		if err != nil {
			return err
		}

		_, err = redisSecuritiesCompany()
		if err != nil {
			return err
		}

		return nil
	}

	return errors.New("券商名称已存在")
}

func (s *SecuritiesCompany) UpdateSecuritiesCompany(se *SecuritiesCompany) error {
	stmt, err := db.Prepare("UPDATE securities_company SET name=?, img=?, official_advantage=?, thick_snow_advantage=?, addr=?, total_promotion_fee=?, promotion_officer_award=?, apprentice_award=?, updated_date=?, rules=? WHERE id=?")
	if err != nil {
		return err
	}

	_, err = stmt.Exec(se.Name, se.Img, se.OfficialAdvantage, se.ThickSnowAdvantage, se.Addr, se.TotalPromotionFee, se.PromotionOfficerAward, se.ApprenticeAward, time.Now().Unix(), se.Rules, se.Id)
	if err != nil {
		return err
	}

	_, err = redisSecuritiesCompany()
	if err != nil {
		return err
	}

	return nil
}

func (s *SecuritiesCompany) DeleteSecuritiesCompany(status int, id int) error {
	stmt, err := db.Prepare("UPDATE securities_company SET status=? WHERE id=?")
	if err != nil {
		return err
	}

	_, err = stmt.Exec(status, id)
	if err != nil {
		return err
	}

	_, err = redisSecuritiesCompany()
	if err != nil {
		return err
	}

	return nil
}
